/* prototype base intervalometer */
Intervalometer = Class.create({
	initialize: function(timeout, callback) {
		this.timeout = timeout;
		this.callback = callback;
		this.start = this._start.bind(this);
		this.stop = this._stop.bind(this);
		this.restart = this._restart.bind(this);
		this.running = false;
		this._timeout = null;
		this.count = 0;
		this.start_time = -1;
		this.last_time = 0;
		this.current_time = 0;
		this.end_time = -1;
		this.run_time = 0;
		this.total_time = -1;
	},
	
	get_time: function() {
		return (new Date().getTime()) - this.start_time;
	},
	
	_start: function() {
		this.start_time = (new Date().getTime());
		if (!this.running) {
			this.running = true;
			this._timeout = setInterval(this._intervalate.bind(this), this.timeout);
			this._intervalate();
		}
	},
	
	_stop: function() {
		clearTimeout(this._timeout);
		this.end_time = (new Date().getTime());
		this.total_time = this.end_time - this.start_time;
		this.running = false;
	},
	
	_restart: function() {
		this.last_time = (new Date().getTime());
		this.count = 0;
		this.start();
	},
	
	_intervalate: function() {
		this.current_time = (new Date().getTime());
		this.run_time = this.current_time - this.start_time;
		if (!this.callback(this)) {
			this._stop();
		}
		this.last_time = this.current_time;
		this.count += 1;
	}
});


FixedIntervalometer = Class.create({
	initialize: function(time, interval, callback) {
		this.time = time;
		this.interval = new Intervalometer(interval, this._update.bind(this));
		this.forward = this._forward.bind(this);
		this.revers = this._revers.bind(this);
		this.callback = callback;
		this.direction = 0;
	},
	_forward: function() {
		if (this.direction == -1) {
			this.direction = 1;
			var t = (new Date().getTime()) 
			this.interval.start_time = t - (this.time - this.interval.get_time());
		} else if (this.direction == 0) {
			this.direction = 1;
			this.interval.start();
		}
	},
	
	_revers: function() {
		if (this.direction == 1) {
			this.direction = -1;
			var t = (new Date().getTime()) 
			this.interval.start_time = t - (this.time - this.interval.get_time());
		} else if (this.direction == 0) {
			this.direction = -1;
			this.interval.start();
		}
	},
	
	_update: function(interval) {
		if (interval.run_time > this.time)
			interval.run_time = this.time;

		if (this.direction == 1) {
			this.callback(interval.run_time / this.time);
		} else if (this.direction == -1) {
			this.callback((this.time - interval.run_time) / this.time);
		} else {
			this.callback(1);
			interval.stop();
		}
		
		if (interval.run_time == this.time) {
			interval.stop();
			this.direction = 0;
		}
			
		return interval.run_time < this.time;
	}
});
